package com.guideir.ota;

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.UpdateEngine;
import android.os.UpdateEngineCallback;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONException;

import java.io.File;
import java.util.ArrayList;

public class MainActivity extends Activity {

    private static final String TAG = "MainActivity";
    private static final int PERCENT_MAX = 100;
    private static final String REBOOT_REASON = "reboot-ab-update";
    private static String download_url;

    private TextView tv_version_info;
    private TextView tv_download_status;
    private TextView tv_update_status;
    private EditText et_ip_addr;
    private ProgressBar mProgressBar;
    private PowerManager mPowerManager;
    private final UpdateEngine mUpdateEngine = new UpdateEngine();
    private final GdUpdateEngineCallback mGdUpdateEngineCallback = new GdUpdateEngineCallback();
    private boolean mInstallationInProgress = false;
    private int downloadFileMaxSize = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_ip_addr = findViewById(R.id.et_ip_addr);
        tv_version_info = findViewById(R.id.tv_version_info);
        tv_version_info.setMovementMethod(ScrollingMovementMethod.getInstance());
        tv_version_info.setText("System Information:\n");
        tv_download_status = findViewById(R.id.tv_download_status);
        tv_update_status = findViewById(R.id.tv_update_status);
        Button bt_update_info = findViewById(R.id.bt_update_info);
        bt_update_info.setOnClickListener(new bt_update_info_listener());
        Button bt_download_ota_package = findViewById(R.id.bt_download_ota_package);
        bt_download_ota_package.setOnClickListener(new bt_download_ota_package_listener());
        Button bt_upgrade_system = findViewById(R.id.bt_upgrade_system);
        bt_upgrade_system.setOnClickListener(new bt_upgrade_system_listener());
        Button bt_system_reboot = findViewById(R.id.bt_system_reboot);
        bt_system_reboot.setOnClickListener(new bt_system_reboot_listener());
        mProgressBar = findViewById(R.id.progressBar);
        mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);
    }

    class bt_update_info_listener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            StringBuilder sb = new StringBuilder();
            sb.append("System Information:\n");
            sb.append("Brand:").append(Build.BRAND).append("\n");
            sb.append("Product:").append(Build.PRODUCT).append("\n");
            sb.append("Manufacturer:").append(Build.MANUFACTURER).append("\n");
            sb.append("Device:").append(Build.DEVICE).append("\n");
            sb.append("Model:").append(Build.MODEL).append("\n");
            sb.append("Display:").append(Build.DISPLAY).append("\n");
            sb.append("Fingerprint:").append(Build.FINGERPRINT).append("\n");
            sb.append("Board:").append(Build.BOARD).append("\n");
            sb.append("Hardware:").append(Build.HARDWARE).append("\n");
            sb.append("Host:").append(Build.HOST).append("\n");
            String update_info = UpdateInfo.getJson();
            sb.append("update_info:").append(update_info);
            Log.d(TAG, sb.toString());
            tv_version_info.setText(sb.toString());

            ArrayList<UpdateInfo.OtaPkgInfo> list = null;
            try {
                list = UpdateInfo.getOtaPkgInfoList();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            if (list != null) {
                UpdateInfo.OtaPkgInfo otaPkgInfo = list.get(list.size() - 1);
                //download_url = UpdateInfo.otaServerAddr + otaPkgInfo.getUrl();
                String ipAddr = et_ip_addr.getText().toString();
                download_url = "http://" + ipAddr + ":3000" + otaPkgInfo.getUrl();
                Log.i(TAG, "download_url:" + download_url);
                Toast.makeText(MainActivity.this, download_url, Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(MainActivity.this, "update_info fail!", Toast.LENGTH_SHORT).show();
            }
        }
    }

    public final Handler handler;

    {
        handler = new Handler() {
            public void handleMessage(Message msg) {
                if (!Thread.currentThread().isInterrupted()) {
                    switch (msg.what) {
                        case 0:
                            downloadFileMaxSize = msg.arg1;
                            Log.i(TAG, "downloadFileMaxSize:" + downloadFileMaxSize);
                            break;
                        case 1:
                            int downloadsize = msg.arg1;
                            float percent = ((float)downloadsize/(float) downloadFileMaxSize) * 100;
                            tv_download_status.setText("Downloading: " + percent + "%");
                            //Log.i(TAG, "downloadsize:" + downloadsize);
                            break;
                        case 2:
                            Toast.makeText(getApplicationContext(), "下载完成", Toast.LENGTH_LONG).show();
                            break;
                        case 3:
                            Toast.makeText(getApplicationContext(), "OTA包已存在", Toast.LENGTH_LONG).show();
                            break;
                        default:
                            break;
                    }
                }
            }

        };
    }

    class bt_download_ota_package_listener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            if (download_url == null) {
                Toast.makeText(MainActivity.this, "Please click 'update_info' before downloading", Toast.LENGTH_SHORT).show();
                return;
            }
            HtmlService.downloadOtaPackage(download_url, "ota_package/update.zip", handler);
        }
    }

    /** Reboot the system. */
    private void rebootNow() {
        if (Log.isLoggable(TAG, Log.INFO)) {
            Log.i(TAG, "Rebooting Now.");
        }
        mPowerManager.reboot(REBOOT_REASON);
    }

    /** Handles events from the UpdateEngine. */
    public class GdUpdateEngineCallback extends UpdateEngineCallback {

        @Override
        public void onStatusUpdate(int status, float percent) {
            Log.d(TAG, String.format("onStatusUpdate %d, Percent %.2f", status, percent));
            tv_update_status.setText(String.format("Update progress: %.2f percent\n", (percent * 100)));
            switch (status) {
                case UpdateEngine.UpdateStatusConstants.UPDATED_NEED_REBOOT:
                    //rebootNow();
                    break;
                case UpdateEngine.UpdateStatusConstants.DOWNLOADING:
                    mProgressBar.setProgress((int) (percent * 100));
                    mInstallationInProgress = false;
                    break;
                default:
                    // noop
            }
        }

        @Override
        public void onPayloadApplicationComplete(int errorCode) {
            Log.w(TAG, String.format("onPayloadApplicationComplete %d", errorCode));
        }
    }

    private void startOtaTest() {
        /*
         * update_engine_client --update --follow --payload=file:///data/ota_package/update.zip --offset=9132 --size=709814284 --headers="FILE_HASH=PQ+PmVuZtfDt7FDf7BQ71Qjvp7X4++iZnTOPWn7gJfw=
         * FILE_SIZE=709814284
         * METADATA_HASH=qiWfB9Pio0AG7h1bEqkcflMX+25mw8YQjlPMxIoCuzE=
         * METADATA_SIZE=109756
         * "
         **/
        String url = "file:///data/ota_package/update.zip";
        long payload_offset = 9132;
        long payload_size = 709814284;
        String[] headerKeyValuePairs = {
                "FILE_HASH=PQ+PmVuZtfDt7FDf7BQ71Qjvp7X4++iZnTOPWn7gJfw=",
                "FILE_SIZE=709814284;",
                "METADATA_HASH=qiWfB9Pio0AG7h1bEqkcflMX+25mw8YQjlPMxIoCuzE=",
                "METADATA_SIZE=109756"
        };
        mUpdateEngine.resetStatus();
        mUpdateEngine.bind(mGdUpdateEngineCallback, new Handler(MainActivity.this.getMainLooper()));
        mUpdateEngine.applyPayload(url, payload_offset, payload_size, headerKeyValuePairs);
    }

    private void startOta() {
        UpdateParser.ParsedUpdate mParsedUpdate = null;
        try {
            mParsedUpdate = UpdateParser.parse(new File("/data/ota_package/update.zip"));
            Log.e(TAG, mParsedUpdate.toString());
        } catch(Exception e) {
            Log.e(TAG,"e = " + e.toString());
        }
        if (mParsedUpdate != null) {
            mUpdateEngine.resetStatus();
            mUpdateEngine.bind(mGdUpdateEngineCallback, new Handler(MainActivity.this.getMainLooper()));// 绑定callback
            mUpdateEngine.applyPayload(
                    mParsedUpdate.mUrl, mParsedUpdate.mOffset, mParsedUpdate.mSize, mParsedUpdate.mProps);
        }
    }

    private class bt_upgrade_system_listener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            //if (!mInstallationInProgress) {
                mInstallationInProgress = true;
                Log.w(TAG, "System upgrading ...");
                tv_update_status.setText("Update progress: 0%\n");
                mProgressBar.setIndeterminate(false);//明确显示进度
                mProgressBar.setMax(PERCENT_MAX);//设置进度条最大值
                //startOtaTest();
                startOta();
            //}
        }
    }

    private class bt_system_reboot_listener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            if (mInstallationInProgress) {
                Toast.makeText(MainActivity.this, "System upgrading! Please wait a moment.", Toast.LENGTH_SHORT).show();
                Log.w(TAG, "System upgrading! Please wait a moment.");
                return;
            }
            Toast.makeText(MainActivity.this, "Rebooting ...", Toast.LENGTH_SHORT).show();
            Log.w(TAG, "Rebooting");
            rebootNow();
        }
    }
}



